package org.example.travel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.example.travel.common.BusinessException;
import org.example.travel.common.RedisKeyUtil;
import org.example.travel.dto.EmailPasswordDTO;
import org.example.travel.dto.EmailRegisterDTO;
import org.example.travel.entity.User;
import org.example.travel.mapper.UserMapper;
import org.example.travel.service.UserService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.Random;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {

    private final StringRedisTemplate redisTemplate;
    private final JavaMailSender mailSender;
    private final UserMapper userMapper;

    @Override
    public void sendCode(String email) {
        // 1. 判断邮箱格式
        if (email == null || !email.matches("^[\\w.-]+@[\\w.-]+\\.\\w+$")) {
            throw new BusinessException("邮箱格式错误");
        }

        // 2. 检查邮箱是否已经注册
        LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
        query.eq(User::getEmail, email);
        if (userMapper.selectOne(query) != null) {
            throw new BusinessException("该邮箱已被注册");
        }

        // 3. 生成6位验证码
        String code = String.format("%06d", new Random().nextInt(999999));
        redisTemplate.opsForValue().set(
                RedisKeyUtil.codeKey(email),
                code,
                Duration.ofMinutes(5)
        );

        // 4. 发送邮件
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(email);
        message.setFrom("2541102169@qq.com");
        message.setSubject("travel 注册验证码");
        message.setText("您的验证码是：" + code + "，5分钟内有效。");
        mailSender.send(message);
    }

    @Override
    public void register(EmailRegisterDTO dto) {
        // 1. 校验验证码
        String key = RedisKeyUtil.codeKey(dto.getEmail());
        String realCode = redisTemplate.opsForValue().get(key);
        if (realCode == null || !realCode.equals(dto.getCode())) {
            throw new BusinessException("验证码错误或已过期");
        }

        // 2. 写入数据库
        User user = new User();
        user.setEmail(dto.getEmail());
        user.setUsername(dto.getUsername());
        user.setPassword(dto.getPassword()); // 可以加密后再存
        userMapper.insert(user);

        // 3. 删除验证码
        redisTemplate.delete(key);
    }

    @Override
    public String login(EmailPasswordDTO dto) {
        // 1. 查找用户
        LambdaQueryWrapper<User> query = new LambdaQueryWrapper<>();
        query.eq(User::getEmail, dto.getEmail());
        User user = userMapper.selectOne(query);
        if (user == null || !user.getPassword().equals(dto.getPassword())) {
            throw new BusinessException("账号或密码错误");
        }

        // 2. 生成 token
        String token = UUID.randomUUID().toString();

        // 3. 存入 Redis，仅存 userId
        redisTemplate.opsForValue().set(
                RedisKeyUtil.tokenKey(token),
                String.valueOf(user.getUserId()),
                Duration.ofMinutes(30)
        );

        return token;
    }
}
